using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using RawRestructure.Models;
using RawRestructure.Services.Interfaces;
using System.Text.RegularExpressions;

namespace RawRestructure.Services;

/// <summary>
/// 配置服务实现
/// </summary>
public class ConfigService : IConfigService
{
    private readonly ILogger<ConfigService> _logger;
    private static readonly Regex IniLinePattern = new(@"^\s*(\w+)\s*=\s*(.+?)\s*$", RegexOptions.Compiled);
    
    // 配置文件路径
    private readonly string _configFilePath;
    
    // 默认工作站配置
    private const string DEFAULT_IP = "127.0.0.1";
    private const int DEFAULT_PORT = 50059;
    
    // 默认批量发送配置
    private const int DEFAULT_BATCH_SIZE = 10;
    private const int DEFAULT_INTERVAL_MS = 50;
    private const int DEFAULT_MOCK_DELAY_MS = 500;
    
    // 缓存的工作站配置
    private string _workstationIp = DEFAULT_IP;
    private int _workstationPort = DEFAULT_PORT;
    
    // 缓存的批量发送配置
    private int _batchSize = DEFAULT_BATCH_SIZE;
    private int _intervalMs = DEFAULT_INTERVAL_MS;
    private int _mockDelayMs = DEFAULT_MOCK_DELAY_MS;
    
    // 配置文件节名称
    private const string CONNECTION_SECTION = "connection";
    private const string SEND_SECTION = "send";

    public ConfigService(ILogger<ConfigService> logger)
    {
        _logger = logger;
        
        // 确定配置文件路径
        _configFilePath = Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory, 
            "config.ini");
            
        // 加载工作站配置
        LoadWorkstationConfig();
    }

    public async Task<ImageConfig?> ParseConfigFileAsync(string configPath)
    {
        try
        {
            if (!File.Exists(configPath))
            {
                _logger.LogWarning("配置文件不存在: {ConfigPath}", configPath);
                return null;
            }

            _logger.LogInformation("开始解析配置文件: {ConfigPath}", configPath);

            var config = new ImageConfig();
            var lines = await File.ReadAllLinesAsync(configPath);
            bool inInfoSection = false;

            foreach (var line in lines)
            {
                var trimmedLine = line.Trim();
                
                // 跳过空行和注释行
                if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("#") || trimmedLine.StartsWith(";"))
                    continue;

                // 检查是否是[info]节
                if (trimmedLine.Equals("[info]", StringComparison.OrdinalIgnoreCase))
                {
                    inInfoSection = true;
                    continue;
                }

                // 检查是否是其他节
                if (trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]"))
                {
                    inInfoSection = false;
                    continue;
                }

                // 只处理[info]节中的参数
                if (!inInfoSection)
                    continue;

                var match = IniLinePattern.Match(trimmedLine);
                if (match.Success)
                {
                    var key = match.Groups[1].Value.ToLowerInvariant();
                    var value = match.Groups[2].Value;

                    switch (key)
                    {
                        case "expmode":
                            config.ExpMode = ParseIntParameter(value, 0);
                            break;
                        case "width":
                            config.Width = ParseIntParameter(value, 0);
                            break;
                        case "height":
                            config.Height = ParseIntParameter(value, 0);
                            break;
                        case "fps":
                            config.Fps = ParseIntParameter(value, 0);
                            break;
                        case "kv":
                            config.KV = ParseIntParameter(value, 0);
                            break;
                        case "ma":
                            config.Ma = ParseIntParameter(value, 0);
                            break;
                        case "ms":
                            config.Ms = ParseIntParameter(value, 0);
                            break;
                        case "mas":
                            config.Mas = ParseIntParameter(value, 0);
                            break;
                        default:
                            _logger.LogDebug("未知配置参数: {Key}={Value}", key, value);
                            break;
                    }
                }
            }

            _logger.LogInformation("配置文件解析完成: ExpMode={ExpMode}, 尺寸={Width}x{Height}", 
                config.ExpMode, config.Width, config.Height);

            return config;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "解析配置文件时发生错误: {ConfigPath}", configPath);
            return null;
        }
    }

    public string? DetectConfigFile(string directoryPath)
    {
        try
        {
            var configFileName = "imageinfo.ini";
            var configPath = Path.Combine(directoryPath, configFileName);
            
            if (File.Exists(configPath))
            {
                _logger.LogInformation("发现配置文件: {ConfigPath}", configPath);
                return configPath;
            }

            _logger.LogDebug("配置文件不存在: {ConfigPath}", configPath);
            return null;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "检测配置文件时发生错误: {DirectoryPath}", directoryPath);
            return null;
        }
    }
    
    /// <summary>
    /// 获取工作站IP地址
    /// </summary>
    /// <returns>工作站IP地址</returns>
    public string GetWorkstationIp()
    {
        return _workstationIp;
    }
    
    /// <summary>
    /// 获取工作站端口
    /// </summary>
    /// <returns>工作站端口</returns>
    public int GetWorkstationPort()
    {
        return _workstationPort;
    }
    
    /// <summary>
    /// 获取批量发送批次大小
    /// </summary>
    /// <returns>批次大小</returns>
    public int GetBatchSize()
    {
        return _batchSize;
    }

    /// <summary>
    /// 获取批量发送间隔时间(ms)
    /// </summary>
    /// <returns>间隔时间(ms)</returns>
    public int GetSendIntervalMs()
    {
        return _intervalMs;
    }

    /// <summary>
    /// 获取模拟发送延迟时间(ms)
    /// </summary>
    /// <returns>延迟时间(ms)</returns>
    public int GetMockDelayMs()
    {
        return _mockDelayMs;
    }
    
    /// <summary>
    /// 保存工作站配置
    /// </summary>
    /// <param name="ip">IP地址</param>
    /// <param name="port">端口</param>
    public void SaveWorkstationConfig(string ip, int port)
    {
        try
        {
            _workstationIp = string.IsNullOrWhiteSpace(ip) ? DEFAULT_IP : ip;
            _workstationPort = port <= 0 ? DEFAULT_PORT : port;
            
            // 保存到配置文件
            string configContent = "";
            bool connectionSectionExists = false;
            
            // 如果配置文件存在，读取现有内容
            if (File.Exists(_configFilePath))
            {
                bool inConnectionSection = false;
                bool ipWritten = false;
                bool portWritten = false;
                
                var lines = File.ReadAllLines(_configFilePath);
                foreach (var line in lines)
                {
                    var trimmedLine = line.Trim();
                    
                    // 检查是否进入[connection]节
                    if (trimmedLine.Equals($"[{CONNECTION_SECTION}]", StringComparison.OrdinalIgnoreCase))
                    {
                        inConnectionSection = true;
                        connectionSectionExists = true;
                        configContent += line + Environment.NewLine;
                        continue;
                    }
                    
                    // 检查是否离开当前节
                    if (inConnectionSection && trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]"))
                    {
                        // 在离开节前添加未写入的配置
                        if (!ipWritten)
                        {
                            configContent += $"ip={_workstationIp}" + Environment.NewLine;
                        }
                        if (!portWritten)
                        {
                            configContent += $"port={_workstationPort}" + Environment.NewLine;
                        }
                        
                        inConnectionSection = false;
                        configContent += line + Environment.NewLine;
                        continue;
                    }
                    
                    // 在connection节中修改已有的配置
                    if (inConnectionSection)
                    {
                        var match = IniLinePattern.Match(trimmedLine);
                        if (match.Success)
                        {
                            var key = match.Groups[1].Value.ToLowerInvariant();
                            
                            if (key == "ip")
                            {
                                configContent += $"ip={_workstationIp}" + Environment.NewLine;
                                ipWritten = true;
                                continue;
                            }
                            else if (key == "port")
                            {
                                configContent += $"port={_workstationPort}" + Environment.NewLine;
                                portWritten = true;
                                continue;
                            }
                        }
                    }
                    
                    // 添加其他行
                    configContent += line + Environment.NewLine;
                }
                
                // 如果在connection节中没有写入配置，在文件末尾添加
                if (connectionSectionExists && inConnectionSection)
                {
                    if (!ipWritten)
                    {
                        configContent += $"ip={_workstationIp}" + Environment.NewLine;
                    }
                    if (!portWritten)
                    {
                        configContent += $"port={_workstationPort}" + Environment.NewLine;
                    }
                }
            }
            
            // 如果没有connection节，添加新节
            if (!connectionSectionExists)
            {
                if (!string.IsNullOrEmpty(configContent))
                {
                    configContent += Environment.NewLine;
                }
                
                configContent += $"[{CONNECTION_SECTION}]" + Environment.NewLine;
                configContent += $"ip={_workstationIp}" + Environment.NewLine;
                configContent += $"port={_workstationPort}" + Environment.NewLine;
            }
            
            // 写入配置文件
            File.WriteAllText(_configFilePath, configContent);
            _logger.LogInformation("已保存工作站配置: IP={IP}, Port={Port}", _workstationIp, _workstationPort);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "保存工作站配置时发生错误");
        }
    }
    
    /// <summary>
    /// 加载工作站配置
    /// </summary>
    private void LoadWorkstationConfig()
    {
        try
        {
            if (!File.Exists(_configFilePath))
            {
                _logger.LogInformation("配置文件不存在，将使用默认配置: {ConfigPath}", _configFilePath);
                // 创建默认配置文件
                SaveWorkstationConfig(DEFAULT_IP, DEFAULT_PORT);
                return;
            }
            
            _logger.LogInformation("开始加载配置: {ConfigPath}", _configFilePath);
            
            bool inConnectionSection = false;
            bool inSendSection = false;
            string ip = DEFAULT_IP;
            int port = DEFAULT_PORT;
            
            var lines = File.ReadAllLines(_configFilePath);
            foreach (var line in lines)
            {
                var trimmedLine = line.Trim();
                
                // 跳过空行和注释行
                if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("#") || trimmedLine.StartsWith(";"))
                    continue;
                
                // 检查是否是[connection]节
                if (trimmedLine.Equals($"[{CONNECTION_SECTION}]", StringComparison.OrdinalIgnoreCase))
                {
                    inConnectionSection = true;
                    inSendSection = false;
                    continue;
                }
                
                // 检查是否是[send]节
                if (trimmedLine.Equals($"[{SEND_SECTION}]", StringComparison.OrdinalIgnoreCase))
                {
                    inConnectionSection = false;
                    inSendSection = true;
                    continue;
                }
                
                // 检查是否是其他节
                if (trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]"))
                {
                    inConnectionSection = false;
                    inSendSection = false;
                    continue;
                }
                
                // 处理配置参数
                var match = IniLinePattern.Match(trimmedLine);
                if (match.Success)
                {
                    var key = match.Groups[1].Value.ToLowerInvariant();
                    var value = match.Groups[2].Value;
                    
                    // 处理[connection]节中的参数
                    if (inConnectionSection)
                    {
                        switch (key)
                        {
                            case "ip":
                                ip = value;
                                break;
                            case "port":
                                port = ParseIntParameter(value, DEFAULT_PORT);
                                break;
                        }
                    }
                    // 处理[send]节中的参数
                    else if (inSendSection)
                    {
                        switch (key)
                        {
                            case "batch_size":
                                _batchSize = ParseIntParameter(value, DEFAULT_BATCH_SIZE);
                                break;
                            case "interval_ms":
                                _intervalMs = ParseIntParameter(value, DEFAULT_INTERVAL_MS);
                                break;
                            case "mock_delay_ms":
                                _mockDelayMs = ParseIntParameter(value, DEFAULT_MOCK_DELAY_MS);
                                break;
                        }
                    }
                }
            }
            
            _workstationIp = ip;
            _workstationPort = port;
            _logger.LogInformation("已加载工作站配置: IP={IP}, Port={Port}", _workstationIp, _workstationPort);
            _logger.LogInformation("已加载批量发送配置: 批次大小={BatchSize}, 间隔={IntervalMs}ms, 模拟延迟={MockDelayMs}ms", 
                _batchSize, _intervalMs, _mockDelayMs);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "加载工作站配置时发生错误，将使用默认配置");
            _workstationIp = DEFAULT_IP;
            _workstationPort = DEFAULT_PORT;
        }
    }

    private int ParseIntParameter(string value, int defaultValue)
    {
        if (int.TryParse(value, out int result))
        {
            return result;
        }

        _logger.LogWarning("无法解析整数参数: {Value}，使用默认值: {DefaultValue}", value, defaultValue);
        return defaultValue;
    }
} 